package com.gqj.meter.service.impl;

import com.gqj.common.constant.UserConstants;
import com.gqj.common.exception.ServiceException;
import com.gqj.common.utils.DateUtils;
import com.gqj.common.utils.StringUtils;
import com.gqj.common.utils.bean.BeanValidators;
import com.gqj.meter.domain.MdStockPosInfo;
import com.gqj.meter.mapper.MdStockPosInfoMapper;
import com.gqj.meter.service.IMdStockPosInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Validator;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 储位信息Service业务层处理
 *
 * @author lxq
 * @date lxq-01-09
 */
@Service
public class MdStockPosInfoServiceImpl implements IMdStockPosInfoService {
    @Autowired
    private MdStockPosInfoMapper mdStockPosInfoMapper;

    @Autowired
    protected Validator validator;
    private static final Logger log = LoggerFactory.getLogger(MdStockPosInfoServiceImpl.class);

    /**
     * 查询储位信息
     *
     * @param storeLocId 储位信息主键
     * @return 储位信息
     */
    @Override
    public MdStockPosInfo selectMdStockPosInfoByStoreLocId(Long storeLocId) {
        return mdStockPosInfoMapper.selectMdStockPosInfoByStoreLocId(storeLocId);
    }

    /**
     * 查询储位信息列表
     *
     * @param mdStockPosInfo 储位信息
     * @return 储位信息
     */
    @Override
    public List<MdStockPosInfo> selectMdStockPosInfoList(MdStockPosInfo mdStockPosInfo) {
        return mdStockPosInfoMapper.selectMdStockPosInfoList(mdStockPosInfo);
    }

    /**
     * 新增储位信息
     *
     * @param mdStockPosInfo 储位信息
     * @return 结果
     */
    @Override
    public int insertMdStockPosInfo(MdStockPosInfo mdStockPosInfo) {
        mdStockPosInfo.setCreateTime(DateUtils.getNowDate());
        return mdStockPosInfoMapper.insertMdStockPosInfo(mdStockPosInfo);
    }

    /**
     * 修改储位信息
     *
     * @param mdStockPosInfo 储位信息
     * @return 结果
     */
    @Override
    public int updateMdStockPosInfo(MdStockPosInfo mdStockPosInfo) {
        mdStockPosInfo.setUpdateTime(DateUtils.getNowDate());
        return mdStockPosInfoMapper.updateMdStockPosInfo(mdStockPosInfo);
    }

    /**
     * 批量删除储位信息
     *
     * @param storeLocIds 需要删除的储位信息主键
     * @return 结果
     */
    @Override
    public int deleteMdStockPosInfoByStoreLocIds(Long[] storeLocIds) {
        return mdStockPosInfoMapper.deleteMdStockPosInfoByStoreLocIds(storeLocIds);
    }

    /**
     * 删除储位信息信息
     *
     * @param storeLocId 储位信息主键
     * @return 结果
     */
    @Override
    public int deleteMdStockPosInfoByStoreLocId(Long storeLocId) {
        return mdStockPosInfoMapper.deleteMdStockPosInfoByStoreLocId(storeLocId);
    }

    /**
     * 校验储位编码是否唯一
     *
     * @param mdStockPosInfo 储位信息
     * @return 结果
     */
    @Override
    public String checkStoreLocNoUnique(MdStockPosInfo mdStockPosInfo) {
        Long storeLocId = StringUtils.isNull(mdStockPosInfo.getStoreLocId()) ? -1L : mdStockPosInfo.getStoreLocId();
        MdStockPosInfo info = mdStockPosInfoMapper.checkStoreLocNoUnique(mdStockPosInfo.getStoreLocNo());
        if (StringUtils.isNotNull(info) && info.getStoreLocId().longValue() != storeLocId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 查询储位下拉框
     *
     * @param mdStockPosInfo 储位
     * @return 储位集合
     */
    public List<Map<String, Object>> mdStockPosInfoOptions(MdStockPosInfo mdStockPosInfo) {
        return mdStockPosInfoMapper.mdStockPosInfoOptions(mdStockPosInfo);
    }

    /**
     * 获取储位统计信息
     *
     * @return 统计信息
     */
    @Override
    public List<Map<String, String>> getStockStatistics() {

        Map<String, Double> originalMap = mdStockPosInfoMapper.getStockStatistics();

        List<Map<String, String>> convertedList = new ArrayList<>();

        DecimalFormat df = new DecimalFormat("0.00");
        if (StringUtils.isNotEmpty(originalMap)) {
            for (Map.Entry<String, Double> entry : originalMap.entrySet()) {
                String name = entry.getKey();
                String formattedValue = df.format(entry.getValue());

                Map<String, String> convertedMap = new HashMap<>();
                convertedMap.put("name", name);
                convertedMap.put("value", formattedValue);
                convertedList.add(convertedMap);
            }
        }


        return convertedList;
    }

    /**
     * 获取货位利用率统计数据
     *
     * @return 结果
     */
    public List<MdStockPosInfo> getPosAvailability() {
        return mdStockPosInfoMapper.getPosAvailability();
    }

    /**
     * 获取储位利用数量比例
     *
     * @return 结果
     */
    public Map<String, Object> getUseStockTotalScale() {
        Integer useStockTotal = mdStockPosInfoMapper.getUseStockTotal();
        Integer stockTotal = mdStockPosInfoMapper.getStockTotal();

        double percentage;
        if (stockTotal == 0) {
            percentage = 0.0;
        } else {
            percentage = (double) useStockTotal / stockTotal * 100;
        }

        Map<String, Object> data = new HashMap<>();
        data.put("value", percentage);
        data.put("name", "储位利用");

        return data;
    }

    /**
     * 导入储位数据
     *
     * @param mdStockPosInfoList 储位列表
     * @param isUpdateSupport    是否更新支持，如果已存在，则进行更新数据
     * @param operName           操作用户
     * @return 结果
     */
    public String importMdStorageAreaInfo(List<MdStockPosInfo> mdStockPosInfoList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(mdStockPosInfoList) || mdStockPosInfoList.size() == 0) {
            throw new ServiceException("导入储位信息不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (MdStockPosInfo mdStockPosInfo : mdStockPosInfoList) {
            try {
                BeanValidators.validateWithException(validator, mdStockPosInfo);
                // 验证是否存在这个数据whNo
                MdStockPosInfo w = mdStockPosInfoMapper.selectMdStockPosInfoByStoreLocNo(mdStockPosInfo.getStoreLocNo());
                if (StringUtils.isNull(w)) {
                    //查询当前最大id
                    Long storeLocId = mdStockPosInfoMapper.selectMaxId();
                    if (null == storeLocId) {
                        storeLocId = (long) 1;
                    } else {
                        storeLocId = storeLocId + 1;
                    }
                    mdStockPosInfo.setStoreLocId(storeLocId);
                    this.insertMdStockPosInfo(mdStockPosInfo);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、储位编号 " + mdStockPosInfo.getStoreLocNo() + " 导入成功");
                } else if (isUpdateSupport) {
                    mdStockPosInfo.setStoreLocId(w.getStoreLocId());
                    this.updateMdStockPosInfo(mdStockPosInfo);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、储位编号 " + mdStockPosInfo.getStoreLocNo() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、储位编号 " + mdStockPosInfo.getStoreLocNo() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、储位编号 " + mdStockPosInfo.getStoreLocNo() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
